JSX - JavaScript en XML
In een vorig hoofdstuk hebben we geleerd hoe je React - Knooppunten kan schrijven in JavaScript. In dit hoofdstuk leer je hoe je React-knooppunten maakt met de JSX-Syntaxis-eXtensie. We leren XML schrijven in onze React-code: JSX is een preprocessorstap, die XML-syntaxis aan JavaScript toevoegt. JSX maakt React een stuk eleganter.
Het gebruik van JSX is niet verplicht voor het schrijven van React. Achter de schermen wordt het createElement
opgeroepen.
Wat is JSX?
React gebruikt JSX, een XML/HTML-achtige syntaxis, waarmee JavaScript uitbreidt wordt zodat XML/HTML-achtige tekst gemengd kan worden met JavaScript/React-code. Deze XML/HTML-achtige syntaxis wordt door een preprocessor, een transpiler zoals Babel, omgezet in JavaScript.
Door JSX te gebruiken, kan je beknopte HTML/XML-achtige structuren (bijvoorbeeld DOM-achtige boomstructuren) in hetzelfde bestand schrijven als waarin je JavaScript-code schrijft. Babel zal deze uitdrukkingen omzetten in JavaScript-code. In tegenstelling tot vroeger, laat JSX ons, in plaats van JavaScript in HTML te plaatsen, HTML in JavaScript te plaatsen.
JSX gebruiken
- Babel - een JavaScript-compiler waarmee ES6 + in oude browsers kan worden gebruikt
Het scripttype van detext/babel
is verplicht wanneer je Babel wilt gebruiken. - een tagnaam
const heading = <h1>Hello, React met JSX!</h1>;
- kinderen
JSX tags kunnen kinderen bevatten, maar geen broers en zussen.
Dit kan:
const element = ( <div> <h1>Hallo Farah</h1> <h2>Welkom bij React JSX!</h2> </div> );
Maar dit niet:
const element = ( <h1>Hello Farah</h1> <h2>Broers en zussen naast elkaar kan niet!</h2> );
- attributen
Met JSX kunnen we ongeveer doen alsof we HTML schrijven. We kunnen dus ook attributen toevoegen aan de tags. Dit is hoe JSX eruit ziet met attributen:
const heading = <h1 className="site-heading" tabIndex="0">Hello, React met JSX!</h1>; ReactDOM.render( heading, document.getElementById('root') );
JSX is eerder JavaScript dan HTML, en dus zijn er zijn een paar belangrijke verschillen met HTML:
className
wordt gebruikt in plaats vanclass
voor het toevoegen van CSS-klassen, omdatclass
een gereserveerd sleutelwoord is in JavaScript.- Eigenschappen en methoden worden in JSX in camelCase geschreven:
onclick
wordtonClick
tabindex
wordttabIndex
- Zelfsluitende tags moeten eindigen met een schuine streep, bijvoorbeeld
<img />
. Ook voor<br />
geldt dat:const element = ( <h1> Hello, {formatName(user)}!<br /> React met JSX </h1> );
- ingesloten JavaScript expressie
- Als een attribuutwaarde tussen aanhalingstekens staat, is de waarde een tekenreeks. Een andere mogelijkheid bestaat erin de waarde tussen accolades te plaatsen en dan is de waarde ingesloten JavaScript-expressie (enclosed JavaScript expression). Je kan om het even welke geldige JavaScript-expressie tussen de accolades in JSX plaatsen:
2 + 8
,user.firstName
of formatName (user)
zijn bijvoorbeeld allemaal geldige JavaScript-expressies.const firstName = 'Farah'; const lastName = 'Rahou'; const element = <h1>Hallo, {firstName} {lastName}</h1>;
- De expressie kan ook een object zijn met CSS regels:
const myStyle = { color: 'white', backgroundColor: 'red', textAlign: 'center', width: '15em', fontSize: '2em;', fontFamily: 'Arial', paddingTop: '0.5em' };
const element = <h1 className="myStyle">Hallo, {firstName} {lastName}</h1>;
- Als een attribuutwaarde tussen aanhalingstekens staat, is de waarde een tekenreeks. Een andere mogelijkheid bestaat erin de waarde tussen accolades te plaatsen en dan is de waarde ingesloten JavaScript-expressie (enclosed JavaScript expression). Je kan om het even welke geldige JavaScript-expressie tussen de accolades in JSX plaatsen:
Toepassen op de Marvel oefening
- Maak een static-react/marvel-jsx.html bestand.
- Het scripttype van de
text/babel
is verplicht wanneer je Babel wilt gebruiken:
<script type="text/babel"> - I.p.v. 15em zijn de tegels hier slechts 10em breed. Ik weet niet waarom dit hier een ander effect in de browser heeft.
- De code:
<!DOCTYPE html> <html lang="nl"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Snel starten met React</title> <!-- Note: when deploying, replace "development.js" with "production.min.js". --> <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> <script type="text/babel"> // we gaan veel keer createElement moeten gebruiken // we maken een afkorting const e = React.createElement; const marvelListStyle = { color: 'green', display: 'flex', flexWrap: 'wrap' }; const marvelItemStyle = { color: 'white', backgroundColor: 'red', textAlign: 'center', width: '10em', fontSize: '2em', fontFamily: 'Arial', paddingTop: '0.5em' }; const marvelImageStyle = { color: 'blue', width: '10em', paddingTop: '0.5em' }; const marvel = ( <div> <h1>Marvel Personnages</h1> <div style={marvelListStyle}> <div style={marvelItemStyle}> Avengers <img src='http://i.annihil.us/u/prod/marvel/i/mg/0/03/523219b086a17.jpg' style={marvelImageStyle} alt="foto van Avengers" /> </div> <div style={marvelItemStyle}> Hulk <img src='http://i.annihil.us/u/prod/marvel/i/mg/5/a0/538615ca33ab0.jpg' style={marvelImageStyle} alt="foto van de Hulk" /> </div> <div style={marvelItemStyle}> Spider-Man <img src='http://i.annihil.us/u/prod/marvel/i/mg/3/50/526548a343e4b.jpg' style={marvelImageStyle} alt="foto van Spider-Man" /> </div> <div style={marvelItemStyle}> Spider-Girl <img src='http://i.annihil.us/u/prod/marvel/i/mg/1/70/4c003adccbe4f.jpg' style={marvelImageStyle} alt="foto van Spider-Girl" /></div> <div style={marvelItemStyle}> X-Man <img src='http://i.annihil.us/u/prod/marvel/i/mg/d/10/535febd73f84f.jpg' style={marvelImageStyle} alt="foto van X-Man" /> </div> </div> </div> ); </script> </head> <body> <div id="root"></div> <script type="text/babel"> ReactDOM.render(marvel, document.querySelector('#root')) </script> </body> </html>
- Met dit als resultaat: